import os
import time
from concurrent.futures import ThreadPoolExecutor

from mp4_downloader import MP4Downloader




class PrintHandler:
    def on_download_start(self, total_bytes: int, support_range: bool, output_dir: str, download_id: str = ""):
        print(f"[event][id={download_id}] 开始下载 MP4，总大小={total_bytes}B，Range支持={support_range}，输出目录={output_dir}")

    def on_segment_start(self, seq: int, filename: str, uri: str, download_id: str = ""):
        print(f"[event][id={download_id}] 开始块/片段: seq={seq}, file={filename}")

    def on_segment_progress(self, seq: int, filename: str, bytes_downloaded: int, elapsed: float, speed_bps: float, download_id: str = ""):
        mb_s = speed_bps / (1024 * 1024)
        kb = bytes_downloaded / 1024
        print(f"[event][id={download_id}] 进度: seq={seq}, {kb:.0f} KB, {mb_s:.2f} MB/s")

    def on_segment_complete(self, seq: int, filename: str, path: str, elapsed: float, size_bytes: int, speed_bps: float, download_id: str = ""):
        mb_s = speed_bps / (1024 * 1024)
        sz_mb = size_bytes / (1024 * 1024)
        print(f"[event][id={download_id}] 完成: seq={seq}, size={sz_mb:.2f} MB, avg={mb_s:.2f} MB/s -> {path}")

    def on_segment_error(self, seq: int, filename: str, error: str, download_id: str = ""):
        print(f"[event][id={download_id}] 失败: seq={seq}, file={filename}, err={error}")

    def on_overall_progress(self, completed: int, total: int, overall_speed_bps: float, download_id: str = ""):
        mb_s = overall_speed_bps / (1024 * 1024)
        pct = (completed / total * 100.0) if total else 0.0
        print(f"[event][id={download_id}] 总体: {completed}/{total} ({pct:.1f}%)，平均速度: {mb_s:.2f} MB/s")

    def on_merge_start(self, total_units: float, unit_label: str | None, output_path: str, download_id: str = ""):
        print(f"[event][id={download_id}] 开始合并 -> {output_path}")

    def on_merge_progress(self, processed: float, total: float, percent: float, download_id: str = ""):
        print(f"[event][id={download_id}] 合并进度: {percent:.1f}% ({processed:.1f}/{total:.1f})")

    def on_merge_complete(self, output_path: str, download_id: str = ""):
        print(f"[event][id={download_id}] 合并完成: {output_path}")

    def on_download_complete(self, output_dir: str, download_id: str = ""):
        print(f"[event][id={download_id}] 下载任务完成，目录: {output_dir}")

    def on_error(self, context: str, message: str, download_id: str = ""):
        print(f"[event][id={download_id}] 错误[{context}]: {message}")


def run_once(url: str, output_dir: str, file_name: str, workers: int, did: str) -> None:
    d = MP4Downloader(
        url=url,
        output_dir=output_dir,
        file_name=file_name,
        max_workers=workers,
        download_id=did,
        event_handler=PrintHandler(),
    )
    d.download()


def main():
    # 写死的参数配置
    VIDEO_URL = "https://rr3---sn-i3bssn7e.googlevideo.com/videoplayback?expire=1761911295&ei=n00EabibCNz3pt8P_u_u0QQ&ip=31.59.133.183&id=o-AGkGBr8Iwn4Eer8lOwoD705-RyUXji24h16i9BPnyaRJ&itag=303&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&met=1761889695%2C&mh=xx&mm=31%2C29&mn=sn-i3bssn7e%2Csn-i3b7knse&ms=au%2Crdu&mv=m&mvi=3&pl=22&rms=au%2Cau&initcwndbps=7647500&bui=AdEuB5SS9FQqQtb4wpv9YpiqYidNUkn9SAbUv5VwnXmiM-VIyBsPfWVVqokGc3xY6ZYkiBVm-k0cG8LE&spc=6b0G_D8FaKGd&vprv=1&svpuc=1&mime=video%2Fwebm&rqh=1&gir=yes&clen=570047392&dur=3705.899&lmt=1750063076189247&mt=1761889270&fvip=3&keepalive=yes&fexp=51552689%2C51565116%2C51565682%2C51580968&c=ANDROID&txp=5537534&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIhAJuzcvYowhFEyO94c3f9xFVoWhph6Gt-RSnZfsrtYN1TAiB_qjRBg3bPLPB3TYQkSK9e0-lYi7znuhg8sbOa6A4YWQ%3D%3D&lsparams=met%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=APaTxxMwRQIgMkhc7l6AJk6pKK2tojebeHpwI1dio6vleNLQuMhoNeQCIQDYU8lcFG86I5LrcQ-U-ME3RQcpJIx04hgP8RDjhTgpQg%3D%3D"
    # 这里需要一个对应的音频直链（同源且可 Range），例如 YouTube 的 itag=140（m4a）。
    # 注意：不同视频的签名/参数不同，示例仅占位，需替换为有效的音频 URL。
    AUDIO_URL = "https://rr3---sn-i3bssn7e.googlevideo.com/videoplayback?expire=1761911295&ei=n00EabibCNz3pt8P_u_u0QQ&ip=31.59.133.183&id=o-AGkGBr8Iwn4Eer8lOwoD705-RyUXji24h16i9BPnyaRJ&itag=251&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&met=1761889695%2C&mh=xx&mm=31%2C29&mn=sn-i3bssn7e%2Csn-i3b7knse&ms=au%2Crdu&mv=m&mvi=3&pl=22&rms=au%2Cau&initcwndbps=7647500&bui=AdEuB5SS9FQqQtb4wpv9YpiqYidNUkn9SAbUv5VwnXmiM-VIyBsPfWVVqokGc3xY6ZYkiBVm-k0cG8LE&spc=6b0G_D8FaKGd&vprv=1&svpuc=1&mime=audio%2Fwebm&rqh=1&gir=yes&clen=69960604&dur=3705.941&lmt=1750056964425820&mt=1761889270&fvip=3&keepalive=yes&fexp=51552689%2C51565116%2C51565682%2C51580968&c=ANDROID&txp=5532534&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIhAJ0mvbJpx_e6KW4YQiQLykAjl4kKgnD3tsGacgBNnmagAiBINQMOABnSUfGhTgp96tnqSqsaTsLPierSyKRnYpWD6g%3D%3D&lsparams=met%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=APaTxxMwRQIgMkhc7l6AJk6pKK2tojebeHpwI1dio6vleNLQuMhoNeQCIQDYU8lcFG86I5LrcQ-U-ME3RQcpJIx04hgP8RDjhTgpQg%3D%3D"
    OUTPUT_DIR = os.path.join(os.getcwd(), "mp4_downloads")
    FILE_NAME = "out.mp4"
    WORKERS = 6

    os.makedirs(OUTPUT_DIR, exist_ok=True)
    did = "mp4test"

    # 第一次运行：可选演示 stop
    d = MP4Downloader(
        url=VIDEO_URL,  # 兼容旧参数，不再必须
        video_url=VIDEO_URL,
        audio_url=AUDIO_URL,
        output_dir=OUTPUT_DIR,
        file_name=FILE_NAME,
        max_workers=WORKERS,
        download_id=did,
        event_handler=PrintHandler(),
    )
    d.download()    


if __name__ == "__main__":
    main()